namespace DotNetNuke.Framework
{
    using DotNetNuke.Common.Utilities;
    using DotNetNuke.Framework.Providers;
    using DotNetNuke.Services.Exceptions;
    using Microsoft.VisualBasic.CompilerServices;
    using System;
    using System.Web.Compilation;

    /// -----------------------------------------------------------------------------
    /// Namespace: DotNetNuke.Framework
    /// Project	 : DotNetNuke
    /// Class	 : Reflection
    /// -----------------------------------------------------------------------------
    /// <summary>
    /// Library responsible for reflection
    /// </summary>
    /// <remarks>
    /// </remarks>
    /// <history>
    /// [Nik Kalyani]	10/15/2004	Replaced brackets in parameter names
    /// [cnurse]	    10/13/2005	Documented
    /// </history>
    /// -----------------------------------------------------------------------------
    public class Reflection
    {
        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Creates an object
        /// </summary>
        /// <typeparam name="T">The type of object to create</typeparam>
        /// <returns></returns>
        /// <remarks>Generic version</remarks>
        /// <history>
        /// [cnurse]	    10/13/2005	Created
        /// </history>
        /// -----------------------------------------------------------------------------
        public static T CreateObject<T>()
        {
            return Activator.CreateInstance<T>();
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Creates an object
        /// </summary>
        /// <param name="ObjectProviderType">The type of Object to create (data/navigation)</param>
        /// <returns>The created Object</returns>
        /// <remarks>Overload for creating an object from a Provider configured in web.config</remarks>
        /// <history>
        /// [cnurse]	    10/13/2005	Documented
        /// </history>
        /// -----------------------------------------------------------------------------
        public static object CreateObject(string ObjectProviderType)
        {
            return CreateObject(ObjectProviderType, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Creates an object
        /// </summary>
        /// <param name="ObjectProviderType">The type of Object to create (data/navigation)</param>
        /// <param name="UseCache">Caching switch</param>
        /// <returns>The created Object</returns>
        /// <remarks>Overload for creating an object from a Provider configured in web.config</remarks>
        /// <history>
        /// [cnurse]	    10/13/2005	Documented
        /// </history>
        /// -----------------------------------------------------------------------------
        public static object CreateObject(string ObjectProviderType, bool UseCache)
        {
            return CreateObject(ObjectProviderType, "", "", "", UseCache);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Creates an object
        /// </summary>
        /// <param name="TypeName">The fully qualified TypeName</param>
        /// <param name="CacheKey">The Cache Key</param>
        /// <returns>The created Object</returns>
        /// <remarks>Overload that takes a fully-qualified typename and a Cache Key</remarks>
        /// <history>
        /// [cnurse]	    10/13/2005	Documented
        /// </history>
        /// -----------------------------------------------------------------------------
        public static object CreateObject(string TypeName, string CacheKey)
        {
            return CreateObject(TypeName, CacheKey, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Creates an object
        /// </summary>
        /// <param name="TypeName">The fully qualified TypeName</param>
        /// <param name="CacheKey">The Cache Key</param>
        /// <param name="UseCache">Caching switch</param>
        /// <returns>The created Object</returns>
        /// <remarks>Overload that takes a fully-qualified typename and a Cache Key</remarks>
        /// <history>
        /// [cnurse]	    10/13/2005	Documented
        /// </history>
        /// -----------------------------------------------------------------------------
        public static object CreateObject(string TypeName, string CacheKey, bool UseCache)
        {
            if (CacheKey == "")
            {
                CacheKey = TypeName;
            }
            Type objType = null;
            if (UseCache)
            {
                objType = (Type) DataCache.GetCache(CacheKey);
            }
            if (objType == null)
            {
                try
                {
                    objType = BuildManager.GetType(TypeName, true);
                    if (UseCache)
                    {
                        DataCache.SetCache(CacheKey, objType);
                    }
                }
                catch (Exception exception1)
                {
                    
                    Exception exc = exception1;
                    DotNetNuke.Services.Exceptions.Exceptions.LogException(exc);
                    
                }
            }
            return Activator.CreateInstance(objType);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Creates an object
        /// </summary>
        /// <param name="ObjectProviderType">The type of Object to create (data/navigation)</param>
        /// <param name="ObjectNamespace">The namespace of the object to create.</param>
        /// <param name="ObjectAssemblyName">The assembly of the object to create.</param>
        /// <returns>The created Object</returns>
        /// <remarks>Overload for creating an object from a Provider including NameSpace and 
        /// AssemblyName ( this allows derived providers to share the same config )</remarks>
        /// <history>
        /// [cnurse]	    10/13/2005	Documented
        /// </history>
        /// -----------------------------------------------------------------------------
        public static object CreateObject(string ObjectProviderType, string ObjectNamespace, string ObjectAssemblyName)
        {
            return CreateObject(ObjectProviderType, "", ObjectNamespace, ObjectAssemblyName, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Creates an object
        /// </summary>
        /// <param name="ObjectProviderType">The type of Object to create (data/navigation)</param>
        /// <param name="ObjectNamespace">The namespace of the object to create.</param>
        /// <param name="ObjectAssemblyName">The assembly of the object to create.</param>
        /// <param name="UseCache">Caching switch</param>
        /// <returns>The created Object</returns>
        /// <remarks>Overload for creating an object from a Provider including NameSpace and 
        /// AssemblyName ( this allows derived providers to share the same config )</remarks>
        /// <history>
        /// [cnurse]	    10/13/2005	Documented
        /// </history>
        /// -----------------------------------------------------------------------------
        public static object CreateObject(string ObjectProviderType, string ObjectNamespace, string ObjectAssemblyName, bool UseCache)
        {
            return CreateObject(ObjectProviderType, "", ObjectNamespace, ObjectAssemblyName, UseCache);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Creates an object
        /// </summary>
        /// <param name="ObjectProviderType">The type of Object to create (data/navigation)</param>
        /// <param name="ObjectProviderName">The name of the Provider</param>
        /// <param name="ObjectNamespace">The namespace of the object to create.</param>
        /// <param name="ObjectAssemblyName">The assembly of the object to create.</param>
        /// <returns>The created Object</returns>
        /// <remarks>Overload for creating an object from a Provider including NameSpace, 
        /// AssemblyName and ProviderName</remarks>
        /// <history>
        /// [cnurse]	    10/13/2005	Documented
        /// </history>
        /// -----------------------------------------------------------------------------
        public static object CreateObject(string ObjectProviderType, string ObjectProviderName, string ObjectNamespace, string ObjectAssemblyName)
        {
            return CreateObject(ObjectProviderType, ObjectProviderName, ObjectNamespace, ObjectAssemblyName, true);
        }

        /// -----------------------------------------------------------------------------
        /// <summary>
        /// Creates an object
        /// </summary>
        /// <param name="ObjectProviderType">The type of Object to create (data/navigation)</param>
        /// <param name="ObjectProviderName">The name of the Provider</param>
        /// <param name="ObjectNamespace">The namespace of the object to create.</param>
        /// <param name="ObjectAssemblyName">The assembly of the object to create.</param>
        /// <param name="UseCache">Caching switch</param>
        /// <returns>The created Object</returns>
        /// <remarks>Overload for creating an object from a Provider including NameSpace, 
        /// AssemblyName and ProviderName</remarks>
        /// <history>
        /// [cnurse]	    10/13/2005	Documented
        /// </history>
        /// -----------------------------------------------------------------------------
        public static object CreateObject(string ObjectProviderType, string ObjectProviderName, string ObjectNamespace, string ObjectAssemblyName, bool UseCache)
        {
            string TypeName = "";
            ProviderConfiguration objProviderConfiguration = ProviderConfiguration.GetProviderConfiguration(ObjectProviderType);
            if ((((ObjectNamespace != "") && (ObjectAssemblyName != "")) ? 1 : 0) != 0)
            {
                if (ObjectProviderName == "")
                {
                    TypeName = ObjectNamespace + "." + objProviderConfiguration.DefaultProvider + ", " + ObjectAssemblyName + "." + objProviderConfiguration.DefaultProvider;
                }
                else
                {
                    TypeName = ObjectNamespace + "." + ObjectProviderName + ", " + ObjectAssemblyName + "." + ObjectProviderName;
                }
            }
            else if (ObjectNamespace != "")
            {
                if (ObjectProviderName == "")
                {
                    TypeName = ObjectNamespace + "." + objProviderConfiguration.DefaultProvider;
                }
                else
                {
                    TypeName = ObjectNamespace + "." + ObjectProviderName;
                }
            }
            else if (ObjectProviderName == "")
            {
                TypeName = ((Provider) objProviderConfiguration.Providers[objProviderConfiguration.DefaultProvider]).Type;
            }
            else
            {
                TypeName = ((Provider) objProviderConfiguration.Providers[ObjectProviderName]).Type;
            }
            return CreateObject(TypeName, TypeName, UseCache);
        }
    }
}

